﻿<!doctype html>
<html>

<head>
    <meta charset="utf-8">
    <style type="text/css">
        body {
            padding: 20px
        }
    </style>
    <link rel="stylesheet" href="index.css">

    <script src="/htmx.js"></script>
    <script type="text/javascript">

    </script>
</head>

<body>
    <button hx-get="/api/index.aardio" 
        hx-swap="innerHTML" 
        hx-trigger="click" 
        hx-target="#info-div"  
        hx-vals='javascript:{myVal: "\
        有以下几种方法指定请求参数：\
        1、在这里直接指定 JSON 作为请求参数。\
        2、使用 javascript: 返回一个 JS 对象作为请求参数。\
        3、如果当前节点是 input，则 name 指定参数名。\
        4、如果当前节点是 form ，则表单内部所有控件的数据作为请求参数。"}'  
        hx-indicator="#indicator">
        点这里发送 GET 请求
    </button><br>

    <!-- 
        上面的 hx-indicator="#indicator" 用 CSS 选择器指定了提交时显示的节点，
        由 index.css 中的 .htmx-request.htmx-indicator 样式指定了提交时切换为显示样式。
        注意 aardio 后端是多线程的，执行耗时操作不会阻塞网页前端。
    -->
    <img id="indicator" class="htmx-indicator" src="/images/loading.gif"/>

    <div id="info-div">
        使用 htmx 每个 HTML 节点都可以发送 HTTP 请求，<br>
        每个 HTML 节点都可以单独刷新显示服务端返回的 HTML。<br>
        <br> 
        不要为了不写 JavaScript 而不写 JavaScript：<br>  
        <button onclick="aardio.getFile().then( 
            v=> { if(v) document.getElementById('info-div').innerText = v; }
            )">
            JavaScript 直接调用 aardio 函数打开本地文件</button>
    </div><br>

    <input type="text" 
        name="q" 
        hx-post="/api/index.aardio" 
        hx-trigger="keyup changed delay:500ms"
        hx-target="#search-results" 
        placeholder="请输入关键词发送 POST 请求 ..."
        style="width:300px"><br>
    <div id="search-results"></div>
    <br>
    <a href="https://mp.weixin.qq.com/s/UTiu5gXJ7j-hKnewhhF5sA" target="_blank">htmx.js 快速入门</a>
    <canvas id="mycanvas" width="1000" height="700" style="position: fixed;left:0px;top:0px;z-index: -1;"/>
    <script type="text/javascript" src="facecat.js"></script>
    <script type="text/javascript">
        let canvas = document.getElementById("mycanvas"); //绘图区域
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        let gPaint = new FCPaint(); //绘图对象
        gPaint.canvas = canvas;
        scaleCanvas(gPaint);
        //判断是否移动端
        gPaint.isMobile = isMobileMode();
        if (gPaint.isMobile) {
            gPaint.scaleFactorX = 2.5;
            gPaint.scaleFactorY = 2.5;
        }
        //判断主题色
        gPaint.defaultUIStyle = "dark";
        addDefaultEvent(canvas, gPaint);

        //最新数据的字符串
        let latestDataStr = "";

        /*
        * 绘制买卖档
        * view:视图
        * paint:绘图对象
        * clipRect:裁剪区域
        */
        let drawBuySellDiv = function (view, paint, clipRect) {
            let avgHeight = view.size.cy / 10;
            let drawFont = "Default,14";
            if (gPaint.isMobile) {
                drawFont = "Default,12";
            }
            let dTop = 0;
            var dataStrs = latestDataStr.split("~");
            let closePrice = 0;
            let priceList = new Array();
            let volList = new Array();
            let buySellTexts = new Array();
            if (dataStrs.length > 80) {
                closePrice = parseFloat(dataStrs[3]);
                priceList.push(parseFloat(dataStrs[27]));
                priceList.push(parseFloat(dataStrs[25]));
                priceList.push(parseFloat(dataStrs[23]));
                priceList.push(parseFloat(dataStrs[21]));
                priceList.push(parseFloat(dataStrs[19]));
                priceList.push(parseFloat(dataStrs[9]));
                priceList.push(parseFloat(dataStrs[11]));
                priceList.push(parseFloat(dataStrs[13]));
                priceList.push(parseFloat(dataStrs[15]));
                priceList.push(parseFloat(dataStrs[17]));

                volList.push(parseFloat(dataStrs[28]));
                volList.push(parseFloat(dataStrs[26]));
                volList.push(parseFloat(dataStrs[24]));
                volList.push(parseFloat(dataStrs[22]));
                volList.push(parseFloat(dataStrs[20]));
                volList.push(parseFloat(dataStrs[10]));
                volList.push(parseFloat(dataStrs[12]));
                volList.push(parseFloat(dataStrs[14]));
                volList.push(parseFloat(dataStrs[16]));
                volList.push(parseFloat(dataStrs[18]));

                buySellTexts.push("卖5");
                buySellTexts.push("卖4");
                buySellTexts.push("卖3");
                buySellTexts.push("卖2");
                buySellTexts.push("卖1");
                buySellTexts.push("买1");
                buySellTexts.push("买2");
                buySellTexts.push("买3");
                buySellTexts.push("买4");
                buySellTexts.push("买5");
            }
            let textColor = "rgb(200,200,200)";
            if (view.paint.defaultUIStyle == "light") {
                textColor = "rgb(0,0,0)";
            }
            let maxVol = maxValue(volList);
            for (let i = 0; i < 10; i++) {
                let tSize = paint.textSize(buySellTexts[i], drawFont);
                paint.drawText(buySellTexts[i], textColor, drawFont, 5, dTop + avgHeight / 2 - tSize.cy / 2);
                if (priceList.length > 0) {
                    let price = priceList[i];
                    let upDownColor = "rgb(255,0,0)";
                    let upDownColor2 = "rgba(255,0,0,50)";
                    if (price >= closePrice) {
                        upDownColor = "rgb(255,0,0)";
                        upDownColor2 = "rgba(255,0,0,50)";
                    } else if (price < closePrice) {
                        upDownColor = "rgb(0,255,0)";
                        upDownColor2 = "rgba(0,255,0,50)";
                    }
                    if (gPaint.isMobile) {
                        paint.drawText(priceList[i].toFixed(2), upDownColor, drawFont, 40, dTop + avgHeight / 2 - tSize.cy / 2);
                    } else {
                        paint.drawText(priceList[i].toFixed(2), upDownColor, drawFont, 50, dTop + avgHeight / 2 - tSize.cy / 2);
                    }
                    if (maxVol > 0) {
                        if (gPaint.isMobile) {
                            paint.fillRect(upDownColor2, view.size.cx - volList[i] * 50 / maxVol, dTop + 2, view.size.cx, dTop + avgHeight - 2);
                        } else {
                            paint.fillRect(upDownColor2, view.size.cx - volList[i] * 80 / maxVol, dTop + 2, view.size.cx, dTop + avgHeight - 2);
                        }
                    }
                    let volText = volList[i].toFixed(0);
                    let volTextSize = paint.textSize(volText, drawFont);
                    paint.drawText(volList[i].toFixed(0), textColor, drawFont, view.size.cx - volTextSize.cx - 10, dTop + avgHeight / 2 - volTextSize.cy / 2);
                }
                dTop += avgHeight;
            }
        };

        //当前的周期
        let currentCycle = "day";

        /*
        * 点击方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        * clicks:点击次数
        */
        gPaint.onClick = function (view, firstTouch, firstPoint, secondTouch, secondPoint, clicks) {
            onClickDefault(view, firstTouch, firstPoint, secondTouch, secondPoint, clicks);
            if (view.viewName == "btnCycleDay") {
                chart.cycle = "day";
                currentCycle = "day";
                queryHistoryData();
            } else if (view.viewName == "btnCycleTime") {
                chart.cycle = "trend";
                currentCycle = "time";
                queryHistoryData();
            } else if (view.viewName == "btnType1") {
                let tabType = findViewByName("tabType", gPaint.views);
                selectTabPage(tabType, tabType.tabPages[0]);
                invalidateView(tabType);
            } else if (view.viewName == "btnType2") {
                let tabType = findViewByName("tabType", gPaint.views);
                selectTabPage(tabType, tabType.tabPages[1]);
                invalidateView(tabType);
            } else if (view.viewName == "btnType3") {
                let tabType = findViewByName("tabType", gPaint.views);
                selectTabPage(tabType, tabType.tabPages[2]);
                invalidateView(tabType);
            }
            else if (view.viewName) { 
                if (view.viewName.indexOf("Indicator_") == 0) {
                    if (view.text == "BOLL" || view.text == "MA") {
                        chart.mainIndicator = view.text;
                    } else {
                        chart.showIndicator = view.text;
                    }
                    calcChartIndicator(chart);
                    invalidateView(chart);
                } else if (view.viewName.indexOf("Plot_") == 0) {
                    chart.addingPlot = view.viewName.substring(5);
                }
            }
        };

        /*
        * 鼠标按下实现方法
        * view:视图
        * mp:坐标
        * button:按钮
        * clicks:点击次数
        * delta:滚轮值
        */
        gPaint.onMouseDown = function (view, mp, buttons, clicks, delta) {
            if (view.viewType == "chart") {
                if (!view.data || view.data.length == 0) {
                    return;
                }
                if (view.addingPlot.length > 0) {
                    addPlotDefault(view, true, mp, false, mp);
                    view.addingPlot = "";
                    invalidateView(chart);
                } else {
                    touchDownChart(view, true, mp, false, mp);
                    invalidateView(chart);
                }
            }else{
                onMouseDownDefault(view, mp, buttons, clicks, delta);
            }
        };

        /*
        * 触摸开始方法
        * view:视图
        * firstTouch:是否第一次触摸
        * firstPoint:第一次触摸的坐标
        * secondTouch:是否第二次触摸
        * secondPoint:第二次触摸的坐标
        */
        gPaint.onTouchBegin = function (view, firstTouch, firstPoint, secondTouch, secondPoint) {
            if (view.viewType == "chart") {
                if (!view.data || view.data.length == 0) {
                    return;
                }
                if (view.addingPlot.length > 0) {
                    addPlotDefault(view, firstTouch, firstPoint, secondTouch, secondPoint);
                    view.addingPlot = "";
                    invalidateView(chart);
                } else {
                    touchDownChart(view, firstTouch, firstPoint, secondTouch, secondPoint);
                    invalidateView(chart);
                }
            }else{
                onTouchBeginDefault(view, firstTouch, firstPoint, secondTouch, secondPoint);
            }
        };

        /*
        * 重绘背景的实现方法
        * view:视图
        * paint:绘图对象
        * clipRect:裁剪区域
        */
        gPaint.onPaint = function (view, paint, clipRect) {
            onPaintDefault(view, paint, clipRect);
            if (view.viewType == "buysell") {
                drawBuySellDiv(view, paint, clipRect);
            }
        };

        /**
         * 绘制横轴刻度的自定义方法
         * chart:图表
         * paint:绘图对象
         * clipRect:裁剪区域
         * 该逻辑仅针对日K线 
         */
        let drawChartHScale = function(chart, paint, clipRect){
            if (chart.data && chart.data.length > 0 && chart.hScaleHeight > 0) {
                let drawLeft = chart.leftVScaleWidth; //左侧起画点
                let i = chart.firstVisibleIndex; //开始索引
                let lastYear = 0; //缓存年份，用于判断是否换年
                let drawYearsCache = []; //实际绘制到图形上的年份文字
                let lastTextRight = 0; //上个文字的右侧
                let timeCache = []; //保存日期的缓存
                let yearTextLeftCache = []; //绘制年文字的左侧位置缓存
                let yearTextRightCache = []; //绘制年文字的右侧位置缓存
                let textPadding = 5; //两个文字之间的最小间隔
                //逐步递增索引，先绘制年
                while(i <= chart.lastVisibleIndex){
                    let dateObj = new Date();
				    dateObj.setTime(chart.data[i].date); //将时间戳转换为time，并缓存到集合中
                    timeCache.push(dateObj);
                    let year = dateObj.getFullYear(); //从结构中获取年份			
                    let x = getChartX(chart, i); //获取索引对应的位置
                    //判断是否换年，以及是否在绘图区间内
                    if (year != lastYear && x >= drawLeft && x < chart.size.cx - chart.rightVScaleWidth){
                        let month = dateObj.getMonth() + 1; //获取月的结构
                        let xText = year.toString(); //拼接要绘制的文字
                        if (month < 10){
                            xText = xText + "-0" + month.toString(); //如果小于10月要补0
                        }
                        else{
                            xText = xText + "-" + month.toString(); //大于等于10月不用补0
                        }
                        let tSize = paint.textSize(xText, chart.font); //计算要绘制文字的大小
                        paint.drawLine("rgb(100,100,100)", 1, 0, x, chart.size.cy - chart.hScaleHeight, x, chart.size.cy - chart.hScaleHeight + 8) //绘制刻度线
                        //判断是否和上个文字重影
                        if (x - tSize.cx / 2 > lastTextRight + textPadding){
                            paint.drawText(xText, "rgb(200,200,200)", "Default,12", x - tSize.cx / 2, chart.size.cy - chart.hScaleHeight + 8  - tSize.cy / 2 + 7) //绘制文字
                            yearTextLeftCache.push(x - tSize.cx / 2); //将年文字的左侧位置缓存
                            yearTextRightCache.push(x + tSize.cx / 2); //将年文字的右侧位置缓存
                            drawYearsCache.push(year); //缓存要绘制的年
                            lastTextRight = x + tSize.cx / 2; //缓存上个文字的右侧位置
                        }
                        lastYear = year; //记录上次绘制的年份
                    }
                    i = i + 1;	//索引累加
                }	
                //绘制月份
                for(let m = 0; m < drawYearsCache.length; m++){
                    let cacheYear = drawYearsCache[m]; //从缓存中获取年份
                    let lastMonth = 0; //缓存月份，用于判断是否换月
                    i = chart.firstVisibleIndex; //重置开始索引
                    lastTextRight = 0; //重置上个文字的右侧
                    //逐步递增索引
                    while (i <= chart.lastVisibleIndex){
                        let dateObj = timeCache[i - chart.firstVisibleIndex]; //从缓存中获取time
                        let year = dateObj.getFullYear(); //从结构中获取年份
                        //判断是否同一年	
                        if (cacheYear == year){
                            let month = dateObj.getMonth() + 1; //从结构中获取月份
                            let x = getChartX(chart, i);
                            //判断是否换月，以及是否在绘图区间内
                            if(lastMonth != month && x >= drawLeft && x < chart.size.cx - chart.rightVScaleWidth){		
                                let xText = month.toString(); //获取绘制的月份文字
                                let tSize = paint.textSize(xText, chart.font); //计算要绘制文字的大小
                                //判断是否和上个文字重影
                                if(x - tSize.cx / 2 > lastTextRight + textPadding){
                                    if ((x - tSize.cx / 2 > yearTextRightCache[m] + textPadding) 
                                    && ((m == drawYearsCache.length - 1) 
                                    || ((m < drawYearsCache.length - 1) 
                                    && (x + tSize.cx / 2 < yearTextLeftCache[m + 1] - textPadding)))){
                                        paint.drawLine("rgb(100,100,100)", 1, 0, x, chart.size.cy - chart.hScaleHeight, x, chart.size.cy - chart.hScaleHeight + 6); //绘制刻度
                                        paint.drawText(xText, "rgb(200,200,200)", "Default,12", x - tSize.cx / 2, chart.size.cy - chart.hScaleHeight + 8  - tSize.cy / 2 + 7); //绘制文字
                                        lastTextRight = x + tSize.cx / 2; //缓存上个文字的右侧位置
                                    }
                                }
                                lastMonth = month //记录上次绘制的月份
                            }
                        }
                        else if(cacheYear < year){
                            break; //超过区间，退出循环
                        }
                        i = i + 1;	//索引累加
                    }
                }
            }
        };

        /**
         * 绘制横轴刻度的自定义方法
         * chart:图表
         * paint:绘图对象
         * clipRect:裁剪区域
)         * 该逻辑仅针对日K线 
         */
        gPaint.onPaintChartHScale = drawChartHScale;

        /*
         * 单元格
         */
        class FCGridCellEx extends FCGridCell {
            constructor() {
                super();
                this.time = ""; //时间
                this.price = 0; //价格
                this.volume = 0; //量
                this.direction = "B"; //方向
                this.closePrice = 0; //当时的收盘价
            }
        };

        /*
        * 绘制单元格
        * grid:表格
        * row:行
        * column:列
        * cell:单元格
        * paint:绘图对象
        * left:左侧坐标
        * top:上方坐标
        * right:右侧坐标
        * bottom:下方坐标
        */
        gPaint.onPaintGridCell = function (grid, row, column, cell, paint, left, top, right, bottom) {
            if (grid.viewName == "gridPrice") {
                let drawTime = cell.time.substring(8);
                drawTime = drawTime.substring(0, 2) + ":" + drawTime.substring(2, 4);
                let drawFont = "Default,14";
                if (gPaint.isMobile) {
                    drawFont = "Default,12";
                }
                let textColor = "rgb(200,200,200)";
                if (grid.paint.defaultUIStyle == "light") {
                    textColor = "rgb(0,0,0)";
                }
                let tSize = paint.textSize(drawTime, drawFont);
                paint.drawText(drawTime, textColor, drawFont, 5, top + (bottom - top - tSize.cy) / 2);
                if (gPaint.isMobile) {
                    if (cell.price >= cell.closePrice) {
                        paint.drawText(cell.price.toFixed(2), "rgb(255,0,0)", drawFont, 40, top + (bottom - top - tSize.cy) / 2);
                    } else {
                        paint.drawText(cell.price.toFixed(2), "rgb(0,255,0)", drawFont, 40, top + (bottom - top - tSize.cy) / 2);
                    }
                } else {
                    if (cell.price >= cell.closePrice) {
                        paint.drawText(cell.price.toFixed(2), "rgb(255,0,0)", drawFont, 50, top + (bottom - top - tSize.cy) / 2);
                    } else {
                        paint.drawText(cell.price.toFixed(2), "rgb(0,255,0)", drawFont, 50, top + (bottom - top - tSize.cy) / 2);
                    }
                }
                if (cell.direction == "B") {
                    paint.drawText(cell.direction, "rgb(255,0,0)", drawFont, grid.size.cx - 20, top + (bottom - top - tSize.cy) / 2);
                } else if (cell.direction == "S") {
                    paint.drawText(cell.direction, "rgb(0,255,0)", drawFont, grid.size.cx - 20, top + (bottom - top - tSize.cy) / 2);
                }
                let volTextSize = paint.textSize(cell.volume.toFixed(0), drawFont);
                paint.drawText(cell.volume.toFixed(0), textColor, drawFont, grid.size.cx - 22 - volTextSize.cx, top + (bottom - top - volTextSize.cy) / 2);
            } else {
                drawGridCell(grid, row, column, cell, paint, left, top, right, bottom);
            }
        };

        /*
         * 重置大小
         */
        let resizeAll = function () {
            try {
                canvas.width = document.documentElement.clientWidth;
                canvas.height = document.documentElement.clientHeight;
                scaleCanvas(gPaint);
                updateViewDefault(gPaint.views);
            } catch (err) {
                //alert(err);
            }
            invalidate(gPaint);
        };


        /*
        * 监听大小改变
        */
        window.onresize = function () {
            resizeAll();
        };

        /*
        * 旋转监听
        */
        window.onorientationchange = function () {
            resizeAll();
        };

        //解析加载XML
        let xml = `<?xml version="1.0" encoding="utf-8"?>
        <html xmlns="facecat">
          <head>
          </head>
          <body>
            <div type="splitlayout" layoutstyle="toptobottom" bordercolor="none" dock="fill" size="400,400" candragsplitter="true" splitterposition="25,0">
              <div type="layout" backcolor="none" bordercolor="none">
                <input type="button" text="分时" size="80,25" name="btnCycleTime" />
                <input type="button" text="日线" size="80,25" name="btnCycleDay" />
                <select name="cbIndicator" selectedindex="0" size="80,25">
                  <option text="MA" name="Indicator_MA" />
                  <option text="BOLL" name="Indicator_BOLL" />
                  <option text="MACD" name="Indicator_MACD" />
                  <option text="KDJ" name="Indicator_KDJ" />
                  <option text="BIAS" name="Indicator_BIAS" />
                  <option text="BBI" name="Indicator_BBI" />
                  <option text="RSI" name="Indicator_RSI" />
                  <option text="ROC" name="Indicator_ROC" />
                  <option text="WR" name="Indicator_WR" />
                  <option text="DMA" name="Indicator_DMA" />
                  <option text="TRIX" name="Indicator_TRIX" />
                  <option text="CCI" name="Indicator_CCI" />
                </select>
                <select name="cbPlot" selectedindex="0" size="100,25">
                  <option text="直线" name="Plot_Line" />
                  <option text="线段" name="Plot_Segment" />
                  <option text="射线" name="Plot_Ray" />
                  <option text="三角形" name="Plot_Triangle" />
                  <option text="矩形" name="Plot_Rect" />
                  <option text="圆" name="Plot_Cycle" />
                  <option text="外接圆" name="Plot_CircumCycle" />
                  <option text="椭圆" name="Plot_Ellipse" />
                  <option text="角度线" name="Plot_AngleLine" />
                  <option text="线性回归" name="Plot_LRLine" />
                  <option text="线性回归通道" name="Plot_LRChannel" />
                  <option text="对称三角形" name="Plot_SymmetricTriangle" />
                  <option text="线性回归带" name="Plot_LRBand" />
                  <option text="平行四边形" name="Plot_ParalleGram" />
                  <option text="速阻线" name="Plot_SpeedResist" />
                  <option text="斐波扇面" name="Plot_FiboFanline" />
                  <option text="斐波周期线" name="Plot_FiboTimezone" />
                  <option text="百分比线" name="Plot_Percent" />
                  <option text="箱型线" name="Plot_BoxLine" />
                  <option text="泰龙水平线" name="Plot_TironeLevels" />
                  <option text="四等分线" name="Plot_QuadrantLines" />
                  <option text="平行线" name="Plot_Parallel" />
                  <option text="黄金分割线" name="Plot_GoldenRatio" />
                  <option text="箭头线段" name="Plot_ArrowSegment" />
                </select>
              </div>
              <div type="splitlayout" layoutstyle="righttoleft" bordercolor="none" dock="fill" size="400,400" candragsplitter="true" splitmode="absolutesize" splittervisible="true" splitterposition="200,0" name="splitLeftRight">
                <div type="splitlayout" layoutstyle="toptobottom" bordercolor="none" dock="fill" size="400,400" candragsplitter="true" splitterposition="220,1">
                  <input type="custom" cid="buysell" name="buySellDiv" />
                  <div type="splitlayout" layoutstyle="toptobottom" bordercolor="none" dock="fill" size="400,400" candragsplitter="true" splitterposition="25,1">
                    <div bordercolor="none" backcolor="none">
                      <select name="cbType" selectedindex="0" bordercolor="none" size="75,25" align="center" vertical-align="middle">
                        <option text="分时成交" name="btnType1" />
                        <option text="备用页面" name="btnType2" />
                        <option text="备用页面2" name="btnType3" />
                      </select>
                    </div>
                    <div type="tab" backcolor="none" bordercolor="none" name="tabType" selectedindex="0">
                      <div type="tabpage" backcolor="none" bordercolor="none" text="分时成交" headersize="0,0">
                        <table name="gridPrice" headerheight="0" dock="fill">
                          <tr>
                            <th width="199" text="Price" />
                          </tr>
                        </table>
                      </div>
                      <div type="tabpage" backcolor="none" bordercolor="none" text="备用页面" headersize="0,0" />
                      <div type="tabpage" backcolor="none" bordercolor="none" text="备用页面2" headersize="0,0" />
                    </div>
                  </div>
                </div>
                <div name="div1">
                  <chart size="200,200" name="Chart" text="Chart" dock="Fill">
                  </chart>
                </div>
              </div>
            </div>
          </body>
        </html>`;
        if (gPaint.isMobile) {
            xml = xml.replaceAll("splitterposition=\"200,0\" name=\"splitLeftRight\">", "splitterposition=\"280,0\" name=\"splitLeftRight\">");
        }
        renderFaceCat(gPaint, xml);
        let chart = findViewByName("Chart", gPaint.views);
        chart.plotPointSizeChart = 15;
        chart.leftVScaleWidth = 70;
        chart.rightVScaleWidth = 70;
        chart.vScaleDistance = 35;
        chart.hScalePixel = 11;
        chart.hScaleHeight = 35;
        chart.candlePaddingTop = 30;
        chart.candlePaddingBottom = 20;
        chart.volPaddingTop = 20;
        chart.volPaddingBottom = 0;
        chart.indPaddingTop = 20;
        chart.indPaddingBottom = 20;
        chart.vScaleDistance = 35;
        chart.cycle = "day";
        chart.font = "Default,12";
        if (gPaint.isMobile) {
            chart.rightVScaleWidth = 0;
            chart.leftVScaleWidth = 60;
        }

        /*
        * 黑色风格
        */
        let toBlack_Chart = function () {
            chart.paint.defaultUIStyle = "dark";
            chart.backColor = "rgb(0,0,0)";
            chart.borderColor = "rgb(100,100,100)";
            chart.textColor = "rgb(255,255,255)";
            chart.scaleColor = "rgb(100,100,100)";
            chart.crossTipColor = "rgb(50,50,50)";
            chart.crossLineColor = "rgb(100,100,100)";
            chart.gridColor = "rgba(100,100,100,125)";
            chart.indicatorColors = new Array();
            chart.indicatorColors.push("rgb(255,255,255)");
            chart.indicatorColors.push("rgb(255,255,0)");
            chart.indicatorColors.push("rgb(255,0,255)");
            chart.indicatorColors.push("rgb(255,0,0)");
            chart.indicatorColors.push("rgb(0,255,255)");
            chart.indicatorColors.push("rgb(0,255,0)");
            chart.indicatorColors.push("rgb(255,255,0)");
            chart.indicatorColors.push("rgb(255,255,255)");
            for (let i = 0; i < chart.plots.length; i++) {
                let plot = chart.plots[i];
                plot.lineColor = "rgb(255,255,255)";
                plot.pointColor = "rgba(255,255,255,125)";
            }
        };

        /*
        * 白色风格
        */
        let toWhite_Chart = function () {
            chart.paint.defaultUIStyle = "light";
            chart.backColor = "rgb(255,255,255)";
            chart.borderColor = "rgb(150,150,150)";
            chart.textColor = "rgb(0,0,0)";
            chart.scaleColor = "rgb(0,0,0)";
            chart.crossTipColor = "rgb(220,220,220)";
            chart.crossLineColor = "rgb(100,100,100)";
            chart.gridColor = "rgba(0,0,0,125)";
            chart.indicatorColors = new Array();
            chart.indicatorColors.push("rgb(100,100,100)");
            chart.indicatorColors.push("rgb(206,147,27)");
            chart.indicatorColors.push("rgb(150,0,150)");
            chart.indicatorColors.push("rgb(255,0,0)");
            chart.indicatorColors.push("rgb(0,150,150)");
            chart.indicatorColors.push("rgb(0,150,0)");
            chart.indicatorColors.push("rgb(59,174,218)");
            chart.indicatorColors.push("rgb(50,50,50)");
            for (let i = 0; i < chart.plots.length; i++) {
                let plot = chart.plots[i];
                plot.lineColor = "rgb(0,0,0)";
                plot.pointColor = "rgba(0,0,0,125)";
            }
        };

        if (gPaint.defaultUIStyle == "dark") {
            toBlack_Chart();
        } else if (gPaint.defaultUIStyle == "light") {
            toWhite_Chart();
        }
        invalidateView(chart);

        /*
         * 查询数据
         */
        let queryLatestData = function () {
            let url = "http://qt.gtimg.cn/q=sh601857";
            let xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", url, true);
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                    let result = xmlhttp.responseText;
                    latestDataStr = result;
                    let buySellView = findViewByName("buySellDiv", gPaint.views);
                    invalidateView(buySellView);

                    let gridPrice = findViewByName("gridPrice", gPaint.views);
                    gridPrice.rowHeight = 20;
                    let row = new FCGridRow();
                    gridPrice.rows.splice(0, 0, row);
                    let cell = new FCGridCellEx();
                    row.cells.push(cell);
                    var dataStrs = latestDataStr.split("~");
                    cell.price = parseFloat(dataStrs[9]);
                    cell.volume = Math.floor(Math.random() * 50) + 1;
                    cell.direction = Math.floor(Math.random() * 2) == 0 ? "B" : "S";
                    cell.time = dataStrs[30];
                    cell.closePrice = dataStrs[3];
                    invalidateView(gridPrice);
                    if (currentCycle == "day") {
                        let dateStr = cell.time.substring(0, 8);
                        dateStr = dateStr.substring(0, 4) + "-" + dateStr.substring(4, 6) + "-" + dateStr.substring(6, 8);
                        let newDate = new Date(dateStr).getTime();
                        let data = new SecurityData();
                        data.close = parseFloat(dataStrs[3]);
                        data.high = parseFloat(dataStrs[33]);
                        data.low = parseFloat(dataStrs[34]);
                        data.open = parseFloat(dataStrs[5]);
                        data.volume = parseFloat(dataStrs[6]);
                        data.date = newDate;
                        if (chart.data && chart.data.length > 0 && newDate == chart.data[chart.data.length - 1].date) {
                            chart.data[chart.data.length - 1] = data;
                        } else {
                            if (!chart.data) {
                                chart.data = new Array();
                            }
                            chart.data.push(data);
                        }
                        let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
                        chart.lastVisibleIndex = chart.data.length - 1;
                        if (maxVisibleRecord > chart.data.length) {
                            chart.firstVisibleIndex = 0;
                        } else {
                            chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1;
                        }
                        //testDiv4();
                        resetChartVisibleRecord(chart);
                        checkChartLastVisibleIndex(chart);
                        calcChartIndicator(chart);
                        invalidateView(chart);
                    }
                }
            }
            xmlhttp.send(null);
        };

        //请求历史数据
        let queryHistoryData = function () {
            let url = "https://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_dayqfq&param=sh601857,day,,,320,qfq&r=0.9860043111257255";
            if (currentCycle == "time") {
                url = "https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=sh601857";
            }
            let xmlhttp = new XMLHttpRequest();
            xmlhttp.open("GET", url, true);
            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
                    if (chart.cycle == "trend") {
                        chart.autoFillHScale = true;
                    } else {
                        chart.autoFillHScale = false;
                    }
                    chart.hScalePixel = 11;
                    let result = xmlhttp.responseText;
                    let dataList = new Array();
                    if (chart.cycle == "trend") {
                        let idx1 = result.indexOf("\"data\":[\"");
                        result = result.substring(idx1 + "\"data\":[\"".length);
                        let idx2 = result.indexOf("\"]");
                        result = result.substring(0, idx2);
                        let datas = result.split(",");
                        let lastVolume = 0;
                        for (let i = 0; i < datas.length; i++) {
                            let subDatas = datas[i].replaceAll("\"", "").split(" ");
                            let data = new SecurityData();
                            data.close = parseFloat(subDatas[1]);
                            data.high = parseFloat(subDatas[1]);
                            data.low = parseFloat(subDatas[1]);
                            data.open = parseFloat(subDatas[1]);
                            data.volume = parseFloat(subDatas[2]) - lastVolume;
                            lastVolume = parseFloat(subDatas[2]);
                            let dateStr = subDatas[0];
                            let hourStr = dateStr.substring(0, 2);
                            let minuteStr = dateStr.substring(2, 4);
                            data.date = new Date("1970-01-01 " + hourStr + ":" + minuteStr + ":00");
                            dataList.push(data);
                        }
                    } else {
                        let datas = result.split("[");
                        for (let i = 0; i < datas.length; i++) {
                            let subDatas = datas[i].split(",");
                            if (subDatas.length == 7) {
                                let data = new SecurityData();
                                let date = new Date(subDatas[0].replaceAll("'", "").replaceAll("\"", ""));
                                data.close = parseFloat(subDatas[2].replaceAll("'", "").replaceAll("\"", ""));
                                data.high = parseFloat(subDatas[3].replaceAll("'", "").replaceAll("\"", ""));
                                data.low = parseFloat(subDatas[4].replaceAll("'", "").replaceAll("\"", ""));
                                data.open = parseFloat(subDatas[1].replaceAll("'", "").replaceAll("\"", ""));
                                data.volume = parseFloat(subDatas[5].replaceAll("'", "").replaceAll("\"", ""));
                                data.date = date.getTime();
                                dataList.push(data);
                            }
                        }
                    }
                    chart.data = dataList;
                    let maxVisibleRecord = getChartMaxVisibleCount(chart, chart.hScalePixel, getChartWorkAreaWidth(chart));
                    chart.lastVisibleIndex = chart.data.length - 1;
                    if (maxVisibleRecord > chart.data.length) {
                        chart.firstVisibleIndex = 0;
                    } else {
                        chart.firstVisibleIndex = chart.lastVisibleIndex - maxVisibleRecord + 1;
                    }
                    //testDiv4();
                    resetChartVisibleRecord(chart);
                    checkChartLastVisibleIndex(chart);
                    calcChartIndicator(chart);
                    invalidateView(chart);
                }
            }
            xmlhttp.send(null);
        };

        queryHistoryData();
        queryLatestData();
        setInterval(queryLatestData, 3000);
    </script>
</body>

</html>